/**
 * Copyright (c) 2019 Coder League
 * All rights reserved.
 *
 * File：SessionInterceptor.java
 * History:
 *         2019年5月11日: Initially created, Chrise.
 */
package club.coderleague.ilsp.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.AsyncHandlerInterceptor;

import club.coderleague.ilsp.common.domain.beans.UserSession;
import club.coderleague.ilsp.controller.IndexController;
import club.coderleague.ilsp.controller.MobileCustomerController;
import club.coderleague.ilsp.controller.MobileIndexController;
import club.coderleague.ilsp.controller.MobileMemberController;
import club.coderleague.ilsp.controller.MobileMerchantController;

/**
 * 会话拦截器。
 * @author Chrise
 */
public class SessionInterceptor implements AsyncHandlerInterceptor {
	/**
	 * @see org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		String ctx = request.getContextPath();
		String servlet = request.getServletPath();
		
		// 检查请求来源
		RequestOrigin origin = this.parseRequestOrigin(ctx, request.getRequestURI());
		
		HttpSession session = request.getSession(false);
		if (session == null || session.getAttribute(UserSession.SESSION_KEY) == null) {		// 用户会话不存在
			// 构造登录页/绑定页/过期页地址
			String url = null;
			switch (origin) {
				case PC:
					url = ctx + IndexController.REQUEST_PREFIX + IndexController.LOGIN_REQUEST_SUFFIX;
					break;
				case MOBILE:
					url = ctx + MobileIndexController.REQUEST_PREFIX + MobileIndexController.BIND_REQUEST_SUFFIX;
					break;
				case MOBILE_MEMBER:
					url = ctx + MobileMemberController.REQUEST_PREFIX + MobileMemberController.EXPIRE_REQUEST_SUFFIX;
					break;
				case MOBILE_CUSTOMER:
					url = ctx + MobileCustomerController.REQUEST_PREFIX + MobileCustomerController.EXPIRE_REQUEST_SUFFIX;
					break;
				case MOBILE_MERCHANT:
					url = ctx + MobileMerchantController.REQUEST_PREFIX + MobileMerchantController.EXPIRE_REQUEST_SUFFIX;
					break;
			}
			
			// 访问登录页/绑定页/过期页时跳过
			if (url.endsWith(servlet)) return true;
			
			// 重定向到登录页/绑定页/过期页
			response.sendRedirect(url);
			return false;
		}
		
		// 构造登录页/绑定页/过期页/重定向地址
		String url = null, redirect = null;
		switch (origin) {
			case PC:
				url = ctx + IndexController.REQUEST_PREFIX + IndexController.LOGIN_REQUEST_SUFFIX;
				redirect = ctx + IndexController.REQUEST_PREFIX + IndexController.MAIN_REQUEST_SUFFIX;
				break;
			case MOBILE:
				url = ctx + MobileIndexController.REQUEST_PREFIX + MobileIndexController.BIND_REQUEST_SUFFIX;
				redirect = ctx + MobileIndexController.REQUEST_PREFIX + MobileIndexController.BIND_REQUEST_SUFFIX;
				break;
			case MOBILE_MEMBER:
				url = ctx + MobileMemberController.REQUEST_PREFIX + MobileMemberController.EXPIRE_REQUEST_SUFFIX;
				redirect = ctx + MobileMemberController.REQUEST_PREFIX + MobileMemberController.MAIN_REQUEST_SUFFIX;
				break;
			case MOBILE_CUSTOMER:
				url = ctx + MobileCustomerController.REQUEST_PREFIX + MobileCustomerController.EXPIRE_REQUEST_SUFFIX;
				redirect = ctx + MobileCustomerController.REQUEST_PREFIX + MobileCustomerController.MAIN_REQUEST_SUFFIX;
				break;
			case MOBILE_MERCHANT:
				url = ctx + MobileMerchantController.REQUEST_PREFIX + MobileMerchantController.EXPIRE_REQUEST_SUFFIX;
				redirect = ctx + MobileMerchantController.REQUEST_PREFIX + MobileMerchantController.MAIN_REQUEST_SUFFIX;
				break;
		}
		
		// 用户会话存在时访问登录页/绑定页/过期页
		if (url.endsWith(servlet)) {
			response.sendRedirect(redirect);	// 重定向到主页/绑定页
			return false;
		}
		
		return true;
	}
	
	/**
	 * 解析请求源。
	 * @author Chrise 2019年5月29日
	 * @param ctx 上下文路径。
	 * @param uri 请求统一资源标识符。
	 * @return 请求源。
	 */
	private RequestOrigin parseRequestOrigin(String ctx, String uri) {
		if (uri.startsWith(ctx + MobileIndexController.REQUEST_PREFIX)) {
			if (uri.startsWith(ctx + MobileMemberController.REQUEST_PREFIX)) return RequestOrigin.MOBILE_MEMBER;
			else if (uri.startsWith(ctx + MobileCustomerController.REQUEST_PREFIX)) return RequestOrigin.MOBILE_CUSTOMER;
			else if (uri.startsWith(ctx + MobileMerchantController.REQUEST_PREFIX)) return RequestOrigin.MOBILE_MERCHANT;
			else return RequestOrigin.MOBILE;
		} else return RequestOrigin.PC;
	}
	
	/**
	 * 请求源。
	 * @author Chrise
	 */
	private enum RequestOrigin {
		/**
		 * PC端请求。
		 */
		PC,
		/**
		 * 移动端请求。
		 */
		MOBILE,
		/**
		 * 会员商城请求。
		 */
		MOBILE_MEMBER,
		/**
		 * 大客户专区请求。
		 */
		MOBILE_CUSTOMER,
		/**
		 * 商户控制台请求。
		 */
		MOBILE_MERCHANT;
	}
}
